const log4js      = require('../../data/log');
const logger      = log4js.getLogger('info');
const server      = require('../../sip/server');
const http        = require('http');
const constants   = require('../../data/constants');
const fs          = require('fs');
const request     = require("request");
const settingModel= require('../../model/setting');
var ffmpeg        = require('fluent-ffmpeg');
var channelCtrl    = require('./channel');
var channelModel   = require('../../model/channel');
const format      = require('string-format');
const mediaserverModel = require('../../model/mediaserver');

/**
 * 与 ZLMediaKit 交互
 */
let Media={};

/**
 * 记录已使用的端口号
 */
Media.ports={ };

/**
 * 没有首页
 * @param {*} req 
 * @param {*} res 
 */
Media.index = function (req, res){
    // 处理逻辑 ...
    res.send('NOT IMPLEMENTED: index');
}

/**
 * 读取目标媒体服务器配置信息
 * 传入参数：host port secret
 */
Media.getServerConfig = function(req,res){
    let url = format('http://{host}:{port}/index/api/getServerConfig?secret={secret}',req.query);

    http.get(url ,(res0)=>{
        var html="";
        res0.on("data",(data)=>{
            logger.info('data', data)
            html += data;
        });
        res0.on("end",()=>{
            let tmp = JSON.parse(html)
            if(tmp.code === 0){
                tmp.code = constants.httpCode.OK.code
                tmp.message = constants.httpCode.OK.message
            }else{
                tmp.code = constants.httpCode.ILLEGAL_TOKEN.code;
                tmp.message = constants.httpCode.ILLEGAL_TOKEN.message
            }
            res.send(tmp);
        });
    }).on('error',(e)=>{
        logger.error(e);
        res.send(e);
    });
}
/**
 * ZLMediaKit 找不到流的时候请求这个接口
 */
Media.onStreamNotFound=function(req,res){
    res.send({'code':0,'msg':'success'});
};
Media.onFlowReport=function(req,res){
    res.send({'code':0,'msg':'success'});
};

/**
 * ZLMediaKit 启动时调用这个接口
 */
Media.onServerStarted=function(req,res){
    let serverId = req.body['general.mediaServerId'];
    constants.mediaservers[serverId] = req.body;
    res.send({'code':0, 'msg':'success'});
};

/**
 * ZLMediaKit 流没人观看时调用这个接口
 */
Media.onStreamNoneReader=function(req,res){
    logger.info('onStreamNoneReader',req.body);
    /**
    {
    mediaServerId: '',
    app: 'rtp',
    schema: 'rtmp',
    stream: 'v_34020000001320000002_34020000001310000006',
    vhost: '__defaultVhost__'
    }
     */
    let stream = req.body.stream.split('_');

    server.bye(stream[1], stream[2], (ret)=>{
        if(ret){
            res.send({'code':0,'msg':'success'});
        }else{
            res.send({'code':1,'msg':'通道未注册成功'});
        }
    });
};

/**
 * ZLMediaKit 播放节目时调用这个接口
 */
Media.onPlay=function(req,res){
    let mediaServerId = req.body.mediaServerId;
    let stream_id = req.body.stream;
    
    if(!mediaServerId || !stream_id){
        res.send({'code':1, 'msg':'参数错误','param': req.body});
        return;
    }
    logger.info('debug onPlay=================');
    logger.info(mediaServerId, stream_id);
    
    // 获取一个port
    Media.openRtpServer({body:{stream_id:stream_id,media_server_id: mediaServerId}}, (res1, media_host)=>{
        
        // 发invite请求
        let stream = stream_id.split('_');

        if(res1.code == -300){
            // 流已经存在，去查找一下
            Media.listRtpServer(mediaServerId).then((rows)=>{
                let port=0;
                for(var s in rows.data){
                    if(rows.data[s].stream_id == stream_id){
                        port = rows.data[s].port;
                        break;
                    }
                }
                if(port>0){
                    server.invite(media_host, stream[1], stream[2], port, (ret)=>{
                        if(ret){
                            res.send({'code':0,'msg':'success'});
                        }else{
                            res.send({'code':1,'msg':'通道未注册成功'});
                        }
                    });
                }else{
                    res.send({'code':1,'msg':'通道未注册成功'});
                }
            }).catch((err) => {
                logger.error(err);
                res.send({'code':1, 'msg':err,'param': req.body});
            });
        }else{
            // 分配新端口，并发invite消息
            server.invite(media_host, stream[1],stream[2], res1.port, (ret)=>{
                if(ret){
                    res.send({'code':0,'msg':'success'});
                }else{
                    res.send({'code':1,'msg':'通道未注册成功'});
                }
            });
        }
    });
};

/**
 * 播放hls时鉴权，这里暂时全设置为允许观看
 */
Media.onHttpAccess=function(req,res){
    res.send({
        'code':0,
        'err':'',
        path:req.body.path,
        second:600, 
        mediaServerId:req.body.mediaServerId
    });
};

/**
 * 
 * @param {*} req $app,$regist,$schema,$stream,$vhost
 * @param {*} res 
 */
Media.onStreamChanged = async function(req,res){
    let method = req.body.regist;
    // let serverId = req.body.mediaServerId;

    if(method && req.body.schema=='rtsp'){
        // 注册时顺便截图
        let stream = req.body.stream.split('_');

        let rtmp = await channelCtrl.geturl(stream[1], stream[2], 'rtmp_snap');
        logger.info('截图',rtmp);
        
        Media.snap(rtmp, stream[1], stream[2]).then((ret)=>{
            
            channelModel.updateSnap(ret.toString(), stream[1], stream[2]).then(()=>{
                res.send({'code':0, 'msg':'success'});
            }).catch(()=>{
                res.send({'code':1, 'msg':'更新截图信息失败'});
            })
            
        }).catch((err) => {
            logger.error(err);
        });
    }else{
        res.send({'code': 0, 'msg': 'success'});
    }
};

Media.onPublish=function(req,res){
    res.send({'code': 0, 'msg': 'success'});
};

/**
 * 查询rtp列表
 * @param {*} req 
 * @param {*} res 
 */
Media.rtpList=function(req,res){
    let serverId = req.query.media_server_id;
    Media.listRtpServer(serverId).then((list) => {
        res.send(Object.assign(constants.httpCode.OK, {data:list}));
    }).catch((err)=>{
        res.send(Object.assign(constants.httpCode.ILLEGAL_PARAM, {data:err}));
    });
}
/**
 * 调用zlmediaKit的 /index/api/openRtpServer接口 ，用于打开一个rtp端口
 */ 
Media.openRtpServer = async function(req, callback){
    let serverId = req.body.media_server_id;
    let streamId = req.body.stream_id;
    
    let host =await mediaserverModel.getInfoByServerId(serverId);

    let url = host.zlk_api_host + 'index/api/openRtpServer';
    // 选取一个空余端口号
    let max = host.rtp_max_port;
    let min = host.rtp_min_port;
    if(!this.ports.index) this.ports.index = min-1;
    
    let port;
    if(this.ports[streamId]){
        port = this.ports[streamId];
    }else{
        this.ports.index++;
        port = this.ports.index;
        this.ports[streamId] = port;
    }
    if(port>max){
        logger.error('没有可用端口了');
    }else{
        let param ="?secret=" + host.secret + "&port=" + port + "&enable_tcp=1&stream_id=" + streamId;
        logger.info(url + param);
        http.get(url + param ,(res) => {
            var html = "";
            res.on("data",(data)=>{
                html += data;
            });
            res.on("end",()=>{
                callback(JSON.parse(html), host.media_host);
            });
        }).on('error',(e)=>{
            logger.error(e);
        });
    }
};

/**
 * 释放所有rtp资源
 */
Media.resetRtpServer=function(serverId){
    Media.listRtpServer(serverId).then((list)=>{
        for(var i in list.data){
            let stream=list.data[i].stream_id;
            Media.closeRtpServer(serverId, stream);
        }
    }).catch((err) => {
        logger.error(err);
    });
};

/**
 * 调用zlmediaKit的 /index/api/closeRtpServer 
 **/ 
Media.closeRtpServer=async function(serverId, stream){
    let host =await mediaserverModel.getInfoByServerId(serverId);
    let url = host.zlk_api_host + 'index/api/closeRtpServer';
    let param ="?secret=" + host.secret + "&port=0&enable_tcp=false&stream_id=" + stream;
    http.get(url + param ,(res)=>{
        var html="";
        res.on("data",(data)=>{
            html += data;
        });
        res.on("end",()=>{
            logger.log(JSON.parse(html));
        });
    }).on('error',(e)=>{
        logger.error(e);
    });
};

/**
 * 调用zlmediaKit的 /index/api/listRtpServer 
 **/ 
Media.listRtpServer=async function(serverId){
    let host =await mediaserverModel.getInfoByServerId(serverId);
    let p=new Promise(function(resolve,reject){
        let url = host.zlk_api_host + 'index/api/listRtpServer';
        let param ="?secret=" + host.secret;

        http.get(url + param ,(res)=>{
            var html="";
            res.on("data",(data)=>{
                html += data;
            });
            res.on("end",()=>{
                resolve(JSON.parse(html));
            });
        }).on('error',(e)=>{
            logger.error(e);
            reject(e);
        });
    });
    return p;
};
Media.ping=async function(serverId){
    let host =await mediaserverModel.getInfoByServerId(serverId);
    console.log('host',host);
    let p=new Promise(function(resolve,reject){
        let url = host.zlk_api_host + 'index/api/listRtpServer';
        let param ="?secret=" + host.secret;

        console.log('url', url+param);
        http.get(url + param ,(res)=>{
            res.on("end",()=>{
                resolve(true);
            });
        }).on('error',(e)=>{
            resolve(false);
        });
    });
    return p;
};
/**
 * 调用zlmediakit 进行截图操作，暂时不用
 */
Media.snap0=function(query,deviceid,channel){
    let p=new Promise(function(resolve,reject){
        let url = constants.zlmedia.url + 'index/api/getSnap';
        let param ="?" + query;
        let path = settingModel.cache.snap_path + "/" + deviceid + "_" + channel + ".jpg";
        request(url+param).pipe(fs.createWriteStream(path));
        resolve({});
    });
    return p;
};
/**
 * 使用fluent-ffmpeg截图
 */
Media.snap = function(source, deviceid, channel){
    logger.info('snap to' ,settingModel.cache.snap_path , deviceid + "_" + channel + ".jpg", 'source', source);
    let p = new Promise(function(resolve,reject){
        ffmpeg({source: source, timeout: 20})
            .on('filenames', function(filenames) {
                let ret = settingModel.cache.snap_path || '';
                let last = ret.charAt(ret.length-1);
                if(last!='/') ret=ret+'/';
                let first = ret.charAt(0);
                if(first=='.') ret = ret.substring(1,ret.length);
                if(ret.indexOf('/public')==0){
                    ret=ret.replace('/public','');
                }
                resolve(ret + filenames);
            })
            .on('end', function() {
                logger.log('ffmpeg end');
            })
            .on('stderr', function(stderrLine) {
                logger.log('Stderr output: ' + stderrLine);
            })
            .on('error', function(err, stdout, stderr) {
                logger.log('Cannot process video: error =' , err.message);
            }).
            addOption(['-rtsp_transport tcp'])
            .screenshots({
                count: 1,
                // timemarks: [ '00:00:02.000' ],
                folder: settingModel.cache.snap_path ,
                filename: deviceid + "_" + channel + ".jpg",
                size: '640x?',
                timeout: 20
        });
    });
    return p;
};

module.exports=Media;